/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University. All rights reserved.
 * 
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license; 2) All redistributions in binary form
 * must reproduce the above copyright notice, this list of conditions and the
 * disclaimer listed in this license in the documentation and/or other materials
 * provided with the distribution; 3) Any documentation included with all
 * redistributions must include the following acknowledgement:
 * 
 * "This product includes software developed by the Community Grids Lab. For
 * further information contact the Community Grids Lab at
 * http://communitygrids.iu.edu/."
 * 
 * Alternatively, this acknowledgement may appear in the software itself, and
 * wherever such third-party acknowledgments normally appear.
 * 
 * 4) The name Indiana University or Community Grids Lab or NaradaBrokering,
 * shall not be used to endorse or promote products derived from this software
 * without prior written permission from Indiana University. For written
 * permission, please contact the Advanced Research and Technology Institute
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202. 5) Products
 * derived from this software may not be called NaradaBrokering, nor may Indiana
 * University or Community Grids Lab or NaradaBrokering appear in their name,
 * without prior written permission of ARTI.
 * 
 * 
 * Indiana University provides no reassurances that the source code provided
 * does not infringe the patent or any other intellectual property rights of any
 * other entity. Indiana University disclaims any liability to any recipient for
 * claims brought by any other entity based on infringement of intellectual
 * property rights or otherwise.
 * 
 * LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO
 * WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 * NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF
 * INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS.
 * INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS",
 * "VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.
 * LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR
 * ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION
 * GENERATED USING SOFTWARE.
 */
package cgl.narada.discovery.topics.messages;

import java.io.IOException;
import java.io.Serializable;
import java.security.cert.Certificate;
import java.util.Calendar;
import java.util.Vector;

import org.apache.log4j.Logger;

import cgl.narada.util.ObjectMarshaller;

/**
 * Topic Creation Request message <br>
 * Created on Apr 7, 2005
 * 
 * @author Harshawardhan Gadgil (hgadgil@grids.ucs.indiana.edu)
 */
public class TopicCreationRequest implements Serializable {

   static Logger log = Logger.getLogger("TopicCreationRequest");

   static String[] Months = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL",
            "AUG", "SEP", "OCT", "NOV", "DEC" };

   /** The entity ID of the entity requesting the Topic Creation */
   private String entityId;

   /** Info reagarding the creator of this message */
   private String creatorInfo;

   /** How long will this topic live */
   private Calendar lifetime;

   /** Topic info */
   private String topicInfo;

   /** Creator Credentials */
   private Certificate certificate;

   // HG: Added to prevent unauthorized discovery...
   // HG: added Aug 15, 2006
   /** Only these entities will be allowed to discover the topic */
   private Vector allowedToDiscoverBy = new Vector();

   /**
    * Topic Synopsis Type
    * 
    * @see cgl.narada.event.TemplateProfileAndSynopsisTypes
    */
   private int synopsisType;

   /** Topic Synopsis */
   private String topicSynopsis;

   /**
    * Marshalls the object into an array of bytes.
    * 
    * @return an array of bytes representing the marshaller object, null if
    *         error occurs
    */
   public byte[] getBytes() {
      try {
         return ObjectMarshaller.marshall(this);
      } catch (IOException e) {
         log.error("", e);
         return null;
      }
   }

   /**
    * Unmarshalls the bytes as a TopicCreationRequest object
    * 
    * @param objectBytes
    * @return TopicCreationRequest if successful, null if error occurs
    */
   public static TopicCreationRequest createObjectFromBytes(byte[] objectBytes) {
      try {
         return (TopicCreationRequest) ObjectMarshaller.unmarshall(objectBytes);
      } catch (IOException e) {
         log.error("", e);
      } catch (ClassNotFoundException e) {
         log.error("", e);
      }
      return null;
   }

   /**
    * For debugging purposes
    */
   public String toString() {
      StringBuffer result = new StringBuffer();
      result.append("entityID      : " + entityId + "\n");
      result.append("creatorInfo   : " + creatorInfo + "\n");
      result.append("lifetime      : " + printTime(lifetime) + "\n");
      result.append("topicInfo     : " + topicInfo + "\n");
      result.append("synopsisType  : " + synopsisType + "\n");
      result.append("topicSynopsis : " + topicSynopsis + "\n");

      return result.toString();
   }

   public static String printTime(Calendar calendar) {
      // print out a bunch of interesting things

      StringBuffer buff = new StringBuffer();

      buff.append(Months[calendar.get(Calendar.MONTH)] + " "
               + pad(calendar.get(Calendar.DATE), 2, '0') + " "
               + calendar.get(Calendar.YEAR) + " ");

      if (calendar.get(Calendar.AM_PM) == Calendar.PM)
         buff.append(pad(calendar.get(Calendar.HOUR) + 12, 2, '0'));
      else
         buff.append(pad(calendar.get(Calendar.HOUR), 2, '0'));

      buff.append(":" + pad(calendar.get(Calendar.MINUTE), 2, '0') + ":"
               + pad(calendar.get(Calendar.SECOND), 2, '0'));

      return buff.toString();
   }

   public static String pad(int num, int digits, char padding) {
      String x = Integer.toString(num);
      int digits2Pad = digits - x.length();

      for (int i = 0; i < digits2Pad; i++) {
         x = padding + x;
      }
      return x;
   }

   public synchronized final Vector getAllowedToDiscoverBy() {
      return allowedToDiscoverBy;
   }

   public synchronized final void setAllowedToDiscoverBy(
            String dnOfAuthorizedUser) {
      this.allowedToDiscoverBy.add(dnOfAuthorizedUser);
   }

   public synchronized final void removeAllowedToDiscoverBy(
            String dnOfAuthorizedUser) {
      this.allowedToDiscoverBy.remove(dnOfAuthorizedUser);
   }

   /**
    * @return Returns the certificate.
    */
   public synchronized final Certificate getCertificate() {
      return certificate;
   }

   /**
    * @param certificate
    *           The certificate to set.
    */
   public synchronized final void setCertificate(Certificate certificate) {
      this.certificate = certificate;
   }

   /**
    * @return Returns the entityId.
    */
   public synchronized final String getEntityId() {
      return entityId;
   }

   /**
    * @param entityId
    *           The entityId to set.
    */
   public synchronized final void setEntityId(String entityId) {
      this.entityId = entityId;
   }

   /**
    * @return Returns the creatorInfo.
    */
   public synchronized final String getCreatorInfo() {
      return creatorInfo;
   }

   /**
    * @param creatorInfo
    *           The creatorInfo to set.
    */
   public synchronized final void setCreatorInfo(String creatorInfo) {
      this.creatorInfo = creatorInfo;
   }

   /**
    * @return Returns the lifetime.
    */
   public synchronized final Calendar getLifetime() {
      return lifetime;
   }

   /**
    * @param lifetime
    *           The lifetime to set.
    */
   public synchronized final void setLifetime(Calendar lifetime) {
      this.lifetime = lifetime;
   }

   /**
    * @return Returns the synopsisType.
    */
   public synchronized final int getSynopsisType() {
      return synopsisType;
   }

   /**
    * @param synopsisType
    *           The synopsisType to set.
    */
   public synchronized final void setSynopsisType(int synopsisType) {
      this.synopsisType = synopsisType;
   }

   /**
    * @return Returns the topicInfo.
    */
   public synchronized final String getTopicInfo() {
      return topicInfo;
   }

   /**
    * @param topicInfo
    *           The topicInfo to set.
    */
   public synchronized final void setTopicInfo(String topicInfo) {
      this.topicInfo = topicInfo;
   }

   /**
    * @return Returns the topicSynopsis.
    */
   public synchronized final String getTopicSynopsis() {
      return topicSynopsis;
   }

   /**
    * @param topicSynopsis
    *           The topicSynopsis to set.
    */
   public synchronized final void setTopicSynopsis(String topicSynopsis) {
      this.topicSynopsis = topicSynopsis;
   }
}